﻿// Decompiled with JetBrains decompiler
// Type: Netick.Unity.TransformErrorCorrector
// Assembly: Netick.Unity, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: E128C7FD-39ED-4452-86AC-6EC748457030
// Assembly location: D:\WorkSpaceDemo\UPM\NetickForUnity\Netick\Runtime\Netick.Unity.dll
// XML documentation location: D:\WorkSpaceDemo\UPM\NetickForUnity\Netick\Runtime\Netick.Unity.xml

using System;
using UnityEngine;

#nullable disable
namespace Netick.Unity;

/// <summary>
/// Handles prediction error correction smoothing for a transform.
/// </summary>
[Serializable]
public struct TransformErrorCorrector
{
  public Vector3 PosPreRollback;
  public Quaternion RotPreRollback;
  public Vector3 PosError;
  public Quaternion RotError;

  public void Init(Vector3 posValue, Quaternion rotValue)
  {
    this.PosPreRollback = posValue;
    this.RotPreRollback = rotValue;
    this.PosError = new Vector3();
    this.RotError = new Quaternion();
  }

  public void OnPreRollback(Vector3 posValue, Quaternion rotValue)
  {
    this.PosPreRollback = posValue;
    this.RotPreRollback = rotValue;
  }

  public void OnPostResimulation(Vector3 posCurrentValue, Quaternion rotCurrentValue)
  {
    this.PosError += this.PosPreRollback - posCurrentValue;
    this.RotError = Quaternion.Inverse(rotCurrentValue) * this.RotPreRollback * this.RotError;
  }

  public void Render(
    ref Vector3 posInterpolatedValue,
    ref Quaternion rotInterpolatedValue,
    float correctionMultiplier,
    float teleportThreshold,
    float deltaTime)
  {
    this.PosError *= Mathf.Exp(-correctionMultiplier * deltaTime);
    if ((double) this.PosError.magnitude > (double) teleportThreshold)
      this.PosError = new Vector3();
    this.RotError = Quaternion.Slerp(this.RotError, Quaternion.identity, correctionMultiplier * deltaTime);
    posInterpolatedValue += this.PosError;
    rotInterpolatedValue *= this.RotError;
  }
}
